---
description: Deploy Hasura GraphQL Engine with Kubernetes
keywords:
  - hasura
  - docs
  - deployment
  - kubernetes
sidebar_position: 4
sidebar_label: Using Kubernetes
---

import LatestRelease from '@site/src/components/LatestRelease';

# Run Hasura GraphQL Engine on Kubernetes

## Introduction

This guide assumes that you already have Postgres running and helps you set up the Hasura GraphQL Engine on Kubernetes
and connect it to your Postgres database.

## Deploying Hasura using Kubernetes

### Step 1: Get the Kubernetes deployment and service files

The [hasura/graphql-engine/install-manifests](https://github.com/hasura/graphql-engine/tree/stable/install-manifests)
repo contains all installation manifests required to deploy Hasura anywhere. Get the Kubernetes deployment and service
files from there:

```bash
$ wget https://raw.githubusercontent.com/hasura/graphql-engine/stable/install-manifests/kubernetes/deployment.yaml
$ wget https://raw.githubusercontent.com/hasura/graphql-engine/stable/install-manifests/kubernetes/svc.yaml
```

### Step 2: Set the Postgres database url

Edit `deployment.yaml` and set the right database url:

```yaml {2}
env:
  - name: HASURA_METADATA_DATABASE_URL
    value: postgres://<username>:<password>@hostname:<port>/<dbname>
```

Examples of `HASURA_METADATA_DATABASE_URL`:

- `postgres://admin:password@localhost:5432/my-db`
- `postgres://admin:@localhost:5432/my-db` _(if there is no password)_

:::info Note

- If your **password contains special characters** (e.g. #, %, $, @, etc.), you need to URL encode them in the
  `HASURA_METADATA_DATABASE_URL` env var (e.g. %40 for @).

  You can check the [logs](#kubernetes-logs) to see if the database credentials are proper and if Hasura is able to
  connect to the database.

- The Hasura GraphQL Engine needs access permissions on your Postgres database as described in
  [Postgres permissions](/deployment/postgres-requirements.mdx#postgres-permissions).

:::

### Step 3: Create the Kubernetes deployment and service

```bash
$ kubectl create -f deployment.yaml
$ kubectl create -f svc.yaml
```

### Step 4: Open the Hasura Console

The above creates a LoadBalancer type service with port 80. So you should be able to access the Console at the external
IP.

For example, using Docker-for-desktop on Mac:

```bash
$ kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
hasura       LoadBalancer   10.96.214.240   localhost     80:30303/TCP   4m
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP        8m
```

Head to: `http://localhost` and the Console should load!

### Step 5: Track existing tables and relationships

See [Setting up a GraphQL schema using an existing Postgres database](/schema/postgres/using-existing-database.mdx) to
enable GraphQL over the database.

## Securing the GraphQL endpoint {#kubernetes-secure}

To make sure that your GraphQL endpoint and the Hasura Console are not publicly accessible, you need to configure an
admin secret key.

### Add the HASURA_GRAPHQL_ADMIN_SECRET env var

Update the `deployment.yaml` to set the `HASURA_GRAPHQL_ADMIN_SECRET` environment variable.

```yaml {10-11}
...
spec:
   containers:
     ...
     command: ["graphql-engine"]
     args: ["serve", "--enable-console"]
     env:
     - name: HASURA_METADATA_DATABASE_URL
       value: postgres://<username>:<password>@hostname:<port>/<dbname>
     - name: HASURA_GRAPHQL_ADMIN_SECRET
       value: mysecretkey
     ports:
     - containerPort: 8080
       protocol: TCP
     resources: {}
```

:::info Note

The `HASURA_GRAPHQL_ADMIN_SECRET` should never be passed from the client to the Hasura GraphQL Engine as it would give
the client full admin rights to your Hasura instance. See [Authentication & Authorization](/auth/overview.mdx) for
information on setting up authentication.

:::

### (optional) Use the admin secret key with the CLI

In case you're using the CLI to open the Hasura Console, use the `admin-secret` flag when you open the Console:

```bash
hasura console --admin-secret=<myadminsecretkey>
```

## Hasura GraphQL Engine server logs {#kubernetes-logs}

You can check the logs of the Hasura GraphQL Engine deployed on Kubernetes by checking the logs of the GraphQL Engine
service, i.e. `hasura`:

```bash
$ kubectl logs -f svc/hasura

{"timestamp":"2018-10-09T11:20:32.054+0000", "level":"info", "type":"http-log", "detail":{"status":200, "query_hash":"01640c6dd131826cff44308111ed40d7fbd1cbed", "http_version":"HTTP/1.1", "query_execution_time":3.0177627e-2, "request_id":null, "url":"/v1/graphql", "user":{"x-hasura-role":"admin"}, "ip":"127.0.0.1", "response_size":209329, "method":"POST", "detail":null}}
...
```

**See:**

- [https://kubernetes.io/docs/concepts/cluster-administration/logging](https://kubernetes.io/docs/concepts/cluster-administration/logging)
  for more details on logging in Kubernetes.
- [Hasura GraphQL Engine logs](/deployment/logging.mdx) for more details on Hasura logs

## Updating Hasura GraphQL Engine {#kubernetes-update}

This guide will help you update the Hasura GraphQL Engine running on Kubernetes. This guide assumes that you already
have the Hasura GraphQL Engine running on Kubernetes.

### Step 1: Check the latest release version

The current latest version is:

<code>
  hasura/graphql-engine:
  <LatestRelease />
</code>

All the versions can be found at:
[https://github.com/hasura/graphql-engine/releases](https://github.com/hasura/graphql-engine/releases).

### Step 2: Update the container image

In the `deployment.yaml` file, update the image tag to this latest version.

For example, if you had:

```yaml
containers:
  - image: hasura/graphql-engine:v1.0.0-alpha01
```

you should change it to:

<pre>
  <code>
    containers:
    <br />
    {'  '}- image: hasura/graphql-engine:
    <LatestRelease />
  </code>
</pre>

### Step 3: Rollout the change

```bash
$ kubectl replace -f deployment.yaml
```

:::info Note

If you are downgrading to an older version of the GraphQL Engine you might need to downgrade your Metadata catalogue
version as described in [Downgrading Hasura GraphQL Engine](/deployment/downgrading.mdx)

:::

## Advanced

- [Setting up Migrations](/migrations-metadata-seeds/migrations-metadata-setup.mdx)
